package solitaire.gui;

import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collections;

import javax.imageio.ImageIO;
import javax.swing.JPanel;
import solitaire.deck.Card;
import solitaire.deck.CardCollection;
import solitaire.deck.Deck;
import solitaire.deck.Pile;
import solitaire.deck.PileCollection;
import solitaire.deck.PlayPile;
import solitaire.deck.Validation;
import solitaire.deck.Card.Rank;
import solitaire.deck.Card.Suit;
import solitaire.deck.Pile.PileType;

public class MousePanel extends JPanel
{
	private static final long serialVersionUID = 98;
    private PileCollection acePiles;
    private PlayPile playPiles;
    private Deck deck;
    public Deck sDeck;
    private Card tcard;
    
    private CardCollection currentCards;
    private Pile currentPile;
    private BufferedImage img;
    
    public MousePanel( )
    {

    	acePiles = new PileCollection();
    	playPiles = new PlayPile();
    	sDeck = new Deck();
    	deck = new Deck();
    	tcard = new Card(Rank.KING, Suit.CLUBS);
    	
    	
        try 
        {
       	 img = ImageIO.read( new File("pic//img23.jpg") );
        }
        catch(IOException ex)
        {
            System.out.println("Could not find picture:");
            System.exit( -1 );
        }
    
        
        
        newGame(true);
        
    	//System.out.println(shuffleDeck.getFirst());
    	//System.out.println(shuffleDeck.getLast());
    	
		//create a mouselistener to handle mouse button events
        addMouseListener( new MouseHandler( ) );
        //create mousemotionlistener to handle mouse motion events
        addMouseMotionListener( new MouseMotionHandler( ) );
    }

    //Here we paint all the Card and all the piles
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(img,0, 0, this);
    	
        for (Pile obj : acePiles)
        {
        	obj.drawObject(g);
        	
        }
        
        for (Pile obj : playPiles)
        {
        	obj.drawObject(g);
        }        
        
        
        if(currentCards != null)
        {
        	for(Card c : currentCards)
        	{
        		c.drawObject(g);
        	}
        }
    }

    private class MouseHandler extends MouseAdapter
    {
        public void mousePressed(MouseEvent event)
        {
        	
        	currentPile = playPiles.findPile(event.getPoint());
        	currentCards = playPiles.findCardCollection(event.getPoint());
        		//Do nothing if nothing is selected.
        	
        		if (currentCards == null || currentPile == null)
        		{
        			currentCards = null;
        			return;
        		}
        		
        		//Do nothing if turned-down card is clicked with more cards on top.
        		if (currentCards.size() != 1 && !currentCards.getFirst().getIsTurned())
        		{
        			currentCards = null;
        			return;
        		}
        		
        		//If card is turned down and is the top card, turn card, when clicked.
        		
        		if (!currentCards.getFirst().getIsTurned())
        		{
        			currentCards.getFirst().turnCard();
        			currentCards = null;
        			repaint();
        			return;
        		}
        		
        		//Else, remove and storeLocation of cards
            		currentCards.storeLocation();
                	currentPile.removeCards(currentCards);
            		
        	
        	
        	
        }

        public void mouseClicked(MouseEvent event)
        {

        }
        
        public void mouseReleased(MouseEvent event)
        {
        	
        	Pile p = playPiles.findPile(event.getPoint());
        	Pile a = acePiles.findPile(event.getPoint());
        	Pile ap = Validation.canCardBeDoubleClickedOnAce(currentCards, acePiles);
        	
        	if (currentCards == null || currentPile == null)
    		{
    			currentCards = null;
    			return;
    		}
    		
    		//Do nothing if turned-down card is clicked with more cards on top.
    		if (currentCards.size() != 1 && !currentCards.getFirst().getIsTurned())
    		{
    			currentCards = null;
    			return;
    		}
        	
    		if (ap != null && event.getClickCount() ==2)
        	{
        		ap.addCard(currentCards.getFirst());
        		repaint();
        		//Validation.fourKings(acePiles);
        		return;
        	}
    		
        	if (Validation.canBePlacedOnEmptySlot(p, currentCards))
        	{
        		p.addCards(currentCards);
        		repaint();
        		return;
        	}
        	
        	if (Validation.canCardBePlacedOnTopOfPlaypile(p, currentCards))
        	{
        		p.addCards(currentCards);
        		repaint();
        		return;
        	}

        	
        	if (Validation.canCardBePlacedOnAce(a, currentCards))
        	{
        		a.addCard(currentCards.getFirst());
        		repaint();
        		//Validation.fourKings(acePiles);
        		return;
        	}
        	
        	
        	
        	currentCards.restoreLocation();
    		currentPile.addCards(currentCards);
        	
        	repaint();
        	
        }
    }
    
    private class MouseMotionHandler implements MouseMotionListener
    {
        public void mouseMoved(MouseEvent event)
        {
        	//TODO: implement findCard
        	if (playPiles.findCard(event.getPoint()) == null)
                setCursor(Cursor.getDefaultCursor());
            else
                setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
        }

        public void mouseDragged(MouseEvent event)
        {
        	if (currentCards != null)
        	{        		
        		currentCards.setLocation(event.getX(), event.getY());
        	}
           	repaint();
        }
    }
    
    
    public void arrangeCards(boolean b)
    {
    	deck = Deck.newDeck();
    	Collections.shuffle(deck);

    	if (b)
    	{
    		sDeck.clear();
    		sDeck = (Deck) deck.clone();
    	}
    	
    	if (!b)
    	{
    		deck.clear();
    		deck = (Deck) sDeck.clone();
    	}
    	
    	for (int PileNumber = 0; PileNumber < 8; PileNumber++)
    	{
    		Pile playPile = playPiles.get(PileNumber);
    		int numberOfCardsOnPile = (PileNumber < 4)? 7 : 6;
    		for (int i = 0; i < numberOfCardsOnPile; i++)
    		{
    			Card c = deck.remove(0);
    			if(i > 3 || numberOfCardsOnPile == 6)
    			{
    				c.turnCard();
    			}
    				
    			 playPile.addCard(c);
    		}
    			
    	}
    	repaint();
    }   
    
    public void newGame(boolean b)
    {
    	playPiles.clear();
    	acePiles.clear();
    	
    	if (currentCards != null)
    	{
    		currentCards.clear();
    	}
    	
    	
    	Pile acePile;
    	//Create AcePiles
    	for(int i=0; i<4;i++)
    	{
    		acePile = new Pile(PileType.CARDS_POSITION_ONTOP);
    		acePile.setLocation(100+(4*85) + (i*85), 50);
    		acePiles.add(acePile);
    	}
    	
    	
    	Pile playPile;
    	//Create PlayPiles
    	for(int i=0; i<8;i++)
    	{
    		playPile = new Pile(PileType.CARDS_POSITION_BELOW);
    		playPile.setLocation(100+(i*85), 170);
    		playPiles.add(playPile);
    	}
    	    
    	/* CHECK IF FOURKINGS WORKS**
    	for (Pile p : acePiles)
    	{
    		p.addCard(tcard);
    	}
    	
    	Validation.fourKings(acePiles);
    	*/
    	arrangeCards(b); 
    	
    	
    }


    
    
	
}

